(function () {
  // 类型明确
  // function fn(a:number): number {
  //     return a;
  // }

  /**
   * 在定义函数或是类时
   *  如果类型不明确的时候,可以使用泛型
   * ts 的
   */
  function fn<T>(a: T): T {
    console.log(a);
    return a;
  }
  // 可以直接调用具有泛型的函数
  let res1 = fn(10); // 不指定泛型 ts可以自动类型进行推断
  let res2 = fn<string>("hello"); // 指定泛型

  /**
   * 泛型可以指定多个
   */
  function fn2<T, K>(a: T, b: K): T {
    console.log(b, a);
    return a;
  }
  fn2<number, string>(123, "hello");

  /**
   * 限制泛型的范围
   */
  interface Inter {
    length: number;
  }
  /**
   * 希望的类型是实现Inter接口的类型
   * T extends Inter表示泛型T必须是Inter实现类(子类)
   */
  function fn3<T extends Inter>(a: T): number {
    return a.length;
  }
  fn3("123");
  // fn3({a:1}) 必须有length属性
  fn3({ length: 10 });

  class MyClass<T> {
    name: T;
    constructor(name: T) {
      this.name = name;
    }
  }
  const mc = new MyClass<string>('hello');
  console.log(mc);
})();
